package com.sp.fresh_produce.service.impl;

import com.sp.fresh_produce.model.dao.UserMapper;
import com.sp.fresh_produce.model.pojo.User;
import com.sp.fresh_produce.ex.CustomException;
import com.sp.fresh_produce.ex.ExceptionCodeEnum;
import com.sp.fresh_produce.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Objects;

/**
 * 用户领域服务实现
 * <p>
 * 实现用户查询、注册、认证、密码匹配与更新个性签名等能力。
 * 密码加密与匹配依赖 Spring Security 的 {@link org.springframework.security.crypto.password.PasswordEncoder}。
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public User getUserById(Integer id) {
        return userMapper.selectByPrimaryKey(id);
    }

    /**
     * 注册新用户
     * <p>
     * 将明文密码加密后保存。
     */
    @Override
    public int register(String username, String password) {
        // 构建用户实体并对明文密码进行加密
        User user = new User();
        user.setUsername(username);
        String encodedPassword = passwordEncoder.encode(password);
        user.setPassword(encodedPassword);
        // 仅插入非空字段
        return userMapper.insertSelective(user);
    }

    @Override
    public User getUserByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    /**
     * 使用 PasswordEncoder 进行密码匹配
     */
    @Override
    public boolean matchesPassword(String rawPassword, String encodedPassword) {
        // 使用 PasswordEncoder 校验密码是否匹配
        return passwordEncoder.matches(rawPassword, encodedPassword);
    }

    /**
     * 用户认证，支持管理员/普通用户入口的权限区分
     */
    @Override
    public User authenticate(String username, String password, boolean adminRequired) {
        // 1) 基础非空校验
        if (username == null || username.isBlank()) {
            throw new CustomException(ExceptionCodeEnum.NEED_USER_NAME);
        }
        if (password == null || password.isBlank()) {
            throw new CustomException(ExceptionCodeEnum.NEED_PASSWORD);
        }
        // 2) 查询用户并校验口令
        User userFromDb = getUserByUsername(username);
        if (userFromDb == null) {
            throw new CustomException(ExceptionCodeEnum.WRONG_USERNAME_OR_PASSWORD);
        }
        boolean bcryptMatched = matchesPassword(password, userFromDb.getPassword());
        if (!bcryptMatched) {
            // 若是旧的 Argon2 哈希且校验通过，则进行“登录即迁移”为 BCrypt
            if (userFromDb.getPassword() != null && userFromDb.getPassword().startsWith("$argon2")) {
                // 使用当前主编码器重新编码并回写
                String newBcrypt = passwordEncoder.encode(password);
                User toUpdate = new User();
                toUpdate.setId(userFromDb.getId());
                toUpdate.setPassword(newBcrypt);
                userMapper.updateByPrimaryKeySelective(toUpdate);
                // 再次视为通过
            } else {
                throw new CustomException(ExceptionCodeEnum.WRONG_USERNAME_OR_PASSWORD);
            }
        }
        // 3) 鉴权：根据入口区分是否只允许管理员或只允许普通用户
        Integer role = userFromDb.getRole();
        if (adminRequired) {
            // 管理员登录入口：仅允许管理员
            if (role == null || role != 2) {
                throw new CustomException(ExceptionCodeEnum.FORBIDDEN);
            }
        } else {
            // 普通用户登录入口：禁止管理员账号从普通入口登录
            if (role != null && role == 2) {
                throw new CustomException(ExceptionCodeEnum.FORBIDDEN);
            }
        }
        // 4) 返回前清理敏感字段
        userFromDb.setPassword(null);
        return userFromDb;
    }

    /**
     * 注册且校验用户名唯一性
     */
    @Override
    public int registerOrThrow(String username, String password) {
        // 1) 非空校验
        if (username == null || username.isBlank()) {
            throw new CustomException(ExceptionCodeEnum.NEED_USER_NAME);
        }
        if (password == null || password.isBlank()) {
            throw new CustomException(ExceptionCodeEnum.NEED_PASSWORD);
        }
        // 2) 重名校验
        if (getUserByUsername(username) != null) {
            throw new CustomException(ExceptionCodeEnum.USER_EXIST);
        }
        // 3) 执行注册
        return register(username, password);
    }

    /**
     * 更新个性签名，保持幂等（相同内容直接返回成功）
     */
    @Override
    public int updatePersonalizedSignature(Integer operatorUserId, String newSignature) {
        // 登录校验：需要当前操作用户 ID 存在且可查询
        if (operatorUserId == null) throw new CustomException(ExceptionCodeEnum.NOT_LOGIN);
        User operator = userMapper.selectByPrimaryKey(operatorUserId);
        if (operator == null) throw new CustomException(ExceptionCodeEnum.NOT_LOGIN);

        // 归一化签名并做幂等处理（相同内容直接返回成功）
        String signature = newSignature == null ? null : newSignature.trim();
        if (Objects.equals(signature, operator.getPersonalizedSignature())) return 1; // 幂等

        // 仅更新签名字段
        User toUpdate = new User();
        toUpdate.setId(operatorUserId);
        toUpdate.setPersonalizedSignature(signature);
        return userMapper.updateByPrimaryKeySelective(toUpdate);
    }

    
}
